import 'package:built_collection/built_collection.dart';
import 'package:equatable/equatable.dart';
import 'package:mobile_app.core/core/domain/entities/learning_content/lexical_item/lexical_item.dart';
import 'package:mobile_app.home.learning.core/user_progress_block/domain/helpers/compute_point_count/helper.dart';
import 'package:mobile_app.home.learning.core/user_progress_block/domain/helpers/get_next_level_progress_ratio/helper.dart';
import 'package:mobile_app.home.learning.core/user_progress_block/domain/helpers/get_next_level_remaining_point_count/helper.dart';
import 'package:mobile_app.home.learning.core/user_progress_block/domain/helpers/identify_level_index/helper.dart';

part 'result.dart';

abstract class HandleLearningContentOuterUpdate {
  LearningContentOuterUpdateHandlingResult call({
    required BuiltMap<String, LexicalItem> lexicalItemMap,
  });
}

class HandleLearningContentOuterUpdateImpl implements HandleLearningContentOuterUpdate {
  const HandleLearningContentOuterUpdateImpl({
    required ComputePointCount computePointCount,
    required GetNextLevelProgressRatio getNextLevelProgressRatio,
    required GetNextLevelRemainingPointCount getNextLevelRemainingPointCount,
    required IdentifyLevelIndex identifyLevelIndex,
  })  : _computePointCount = computePointCount,
        _getNextLevelProgressRatio = getNextLevelProgressRatio,
        _getNextLevelRemainingPointCount = getNextLevelRemainingPointCount,
        _identifyLevelIndex = identifyLevelIndex;

  final ComputePointCount _computePointCount;
  final GetNextLevelProgressRatio _getNextLevelProgressRatio;
  final GetNextLevelRemainingPointCount _getNextLevelRemainingPointCount;
  final IdentifyLevelIndex _identifyLevelIndex;

  @override
  LearningContentOuterUpdateHandlingResult call({
    required BuiltMap<String, LexicalItem> lexicalItemMap,
  }) {
    final pointCount = _computePointCount(
      lexicalItemMap: lexicalItemMap,
    );

    final levelIndex = _identifyLevelIndex(
      pointCount: pointCount,
    );

    final nextLevelProgressRatio = _getNextLevelProgressRatio(
      levelIndex: levelIndex,
      pointCount: pointCount,
    );

    final nextLevelRemainingPointCount = _getNextLevelRemainingPointCount(
      levelIndex: levelIndex,
      pointCount: pointCount,
    );

    final result = LearningContentOuterUpdateHandlingResult(
      pointCount: pointCount,
      nextLevelRemainingPointCount: nextLevelRemainingPointCount,
      levelIndex: levelIndex,
      nextLevelProgressRatio: nextLevelProgressRatio,
    );

    return result;
  }
}
